<!DOCTYPE html>



  


<html class="theme-next muse use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/blog/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/blog/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/blog/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/blog/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/blog/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/blog/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta property="og:type" content="website">
<meta property="og:title" content="smallmuou&#39;s blog">
<meta property="og:url" content="http://smallmuou.gitee.io/blog/page/20/index.html">
<meta property="og:site_name" content="smallmuou&#39;s blog">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="smallmuou&#39;s blog">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/blog/',
    scheme: 'Muse',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://smallmuou.gitee.io/blog/page/20/"/>





  <title>smallmuou's blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left 
  page-home">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/blog/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">smallmuou's blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"><a href="https://github.com/smallmuou">https://github.com/smallmuou</a></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/blog/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/blog/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            
  <section id="posts" class="posts-expand">
    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/11/18/2014-11-17-敏捷开发落地新范式/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/11/18/2014-11-17-敏捷开发落地新范式/" itemprop="url">敏捷开发落地新范式(MOMOKO)</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-11-18T07:25:06+08:00">
                2014-11-18
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/其他/" itemprop="url" rel="index">
                    <span itemprop="name">其他</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>敏捷开发以用户的需求进化为核心，采用迭代、循序渐进的方法进行软件开发。</p>
<p>敏捷开发宣言:</p>
<ul>
<li>个体和交互胜过过程和工具</li>
<li>可工作的软件胜过面面俱到的文档</li>
<li>客户协作胜过合同谈判</li>
<li>响应变化胜过遵循计划</li>
</ul>
<p>敏捷开发流程:</p>
<p><img src="http://b.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26%3Bt%3Dgif/sign=1004527857fbb2fb202650402e234bc1/241f95cad1c8a78680fd102b6509c93d70cf503b.jpg =800x" alt="image"></p>
<p>作者提出一种落地范式:影响地图-&gt;故事地图-&gt;看板<br><img src="http://127.0.0.1/Desktop/pic1.png =800x" alt="image"></p>
<h2 id="2-影响地图"><a href="#2-影响地图" class="headerlink" title="2.影响地图"></a>2.影响地图</h2><h3 id="为什么"><a href="#为什么" class="headerlink" title="为什么"></a>为什么</h3><ul>
<li>业务职能与开发职能之间交流决策的隔阂<br><img src="http://127.0.0.1/Desktop/pic2.png =800x" alt="image"></li>
<li>业务目标与功能之间映射关系的模糊和不一致</li>
</ul>
<p><img src="http://www.ituring.com.cn/download/01fxSGzi49zd.small" alt="image"></p>
<h3 id="具体内容"><a href="#具体内容" class="headerlink" title="具体内容"></a>具体内容</h3><p><img src="http://retype.wenku.bdimg.com/retype/zoom/343d8fd8b14e852458fb57f9?pn=8&amp;o=jpg_6&amp;md5sum=f9d6a3e25078cdaa4c0e237b3a65b4ff&amp;sign=b9fc63038f&amp;png=134587-151395&amp;jpg=657174-720276 =800x" alt="image"></p>
<ul>
<li>WHY - 就是要实现的业务目标或要解决客户的核心问题是什么<ul>
<li>SMART(具体、可衡量、可达成、相关性、时间性),如”增加付费用户的比例” =&gt; “三个月内付费用户比例从1%增加到1.5%”</li>
</ul>
</li>
<li>WHO － 就是可以通过影响谁的行为来实现目标，或消除实现目标的阻碍<ul>
<li>主要用户（产品的直接使用者）</li>
<li>次要用户（安装和维护人员）</li>
<li>产品关系人(采购的决策者、竞争对手)</li>
</ul>
</li>
<li>HOW - 就是怎样影响角色的行为，来达成目标；这里既包含产生促进目标实现的正面行为，也包含消除阻碍目标实现的负面行为</li>
<li><p>WHAT - 就是要交付什么产品功能或服务产生希望的影响。它决定了产品的范围</p>
</li>
<li><p>功能假设 - 假设通过设想的功能能对角色产生期望的影响</p>
</li>
<li>影响假设 - 假设对角色产生这样的影响会促进目标的实现</li>
</ul>
<h3 id="举例"><a href="#举例" class="headerlink" title="举例"></a>举例</h3><p><img src="http://www.ituring.com.cn/download/01fxSH0CALOd.small" alt="image"></p>
<h2 id="3-故事地图"><a href="#3-故事地图" class="headerlink" title="3.故事地图"></a>3.故事地图</h2><ul>
<li>根据影响地图确定要开发的业务流</li>
<li>确定优先级</li>
<li>并按照优先级的顺序，整理成为一个个的迭代</li>
<li>然后把一个个的迭代拆成一个个可验收的故事卡</li>
</ul>
<p>需求拆分为故事卡的原则是:</p>
<ul>
<li>故事卡是可以独立验收的场景</li>
<li>故事卡包含的点数应该尽量小,如果超过了应该重新拆分该故事卡</li>
</ul>
<h2 id="4-看板"><a href="#4-看板" class="headerlink" title="4.看板"></a>4.看板</h2><p>MASTER把当前Sprint中所有的故事卡贴到故事墙上，等待开发人员的开发。故事墙的模板为:<br><img src="http://yspe2371e4aa7697989.yunshipei.cn/dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJtaHBMbU56Wkc0dWJtVjBKVEpHWVhSMFlXTm9iV1Z1ZENVeVJqSXdNVEV3TmlVeVJqRXlKVEpHTUY4eE16QTNPRFkyTlRrMVVrbDBNeTVuYVdZPQ==" alt="image"></p>
<ul>
<li>分析 － 起始点</li>
<li>等待开发 - 开发人员和SE确认了需求，明确了做什么以及怎么做以后，把故事卡从分析阶段移到等待开发</li>
<li>开发中 - 开发人员一次只开发一张故事卡，把相应开发的那张卡移植到开发中</li>
<li>阻塞 - 如果开发过程中，由于配合的原因，导致故事卡无法继续走下去，则把该卡移动到阻塞阶段</li>
<li>开发完成 - 如果开发完成，并向MASTER  SHOW CASE以后，开发人员吧故事卡移植到等待测试</li>
<li>等待测试 - 测试人员看到等待测试中有卡以后，对故事卡进行测试，测试完成以后把卡移到测试完成阶段，如果测试有问题，则移出该卡到开发中阶段</li>
<li>测试完成 - 本张卡的生命周期结束</li>
</ul>
<p>当然，每个Sprint都有一个总结会议，回顾本次开发过程、梳理好与不好的点，并针对不好的点提出解决方案，以便在下一个Sprint改进.</p>
<h2 id="5-综述"><a href="#5-综述" class="headerlink" title="5.综述"></a>5.综述</h2><p>敏捷是一柄双刃剑，用的好能极大的提升开发效率，适应需求的变化; 用的不好则会导致项目的混乱。<br>敏捷开发提倡一个迭代80%以上的时间都在编程，几乎没有设计的阶段，因为我们必须保证我们的代码的质量。因此在整个迭代过程中我们要持续做到以下几个方面:<br><img src="http://yspe2371e4aa7697989.yunshipei.cn/dHlwZT1mdyZzaXplPTY0MCZzcmM9YUhSMGNDVXpRU1V5UmlVeVJtaHBMbU56Wkc0dWJtVjBKVEpHWVhSMFlXTm9iV1Z1ZENVeVJqSXdNVEV3TmlVeVJqRXhKVEpHTUY4eE16QTNPRE0xT1RjM05EUndNeTVuYVdZPQ==" alt="image"></p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/11/14/2014-11-14-iOS设备配置/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/11/14/2014-11-14-iOS设备配置/" itemprop="url">iOS 设备配置</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-11-14T00:00:00+08:00">
                2014-11-14
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/IOS/" itemprop="url" rel="index">
                    <span itemprop="name">IOS</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>这里将会列表所有iOS设备的配置信息.</p>
<p>名称|CPU|内存|iOS系统|发布日期<br>|:–|:–|:–|:–|:–<br>iPhone3GS|ARMCortex-A8|256M|iOS 3.0|2009-6<br>iPhone4|A4|512M|iOS 5.0|2010-6<br>iPad2|A5|512M|iOS 5.0|2011-3<br>iPhone4s|A5|512M|iOS 5.0|2012-1<br>New iPad|A5X|1G|iOS 5.1|2012-3<br>iPad mini|A5|512M|iOS 6.0|2012-10<br>iPhone5|A6|1G|iOS 6.0|2012-9<br>iPad4|A6X|1G|iOS 6.0|2012-12<br>iPhone5S|A7|1G|iOS 7.0|2013-9<br>iPad Air|A7|1G|iOS 7.0|2013-10<br>iPad mini2|A7|1G|iOS 7.0|2013-10</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/11/14/2014-11-14-sdp协议解读/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/11/14/2014-11-14-sdp协议解读/" itemprop="url">SDP协议解读</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-11-14T00:00:00+08:00">
                2014-11-14
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/音视频/" itemprop="url" rel="index">
                    <span itemprop="name">音视频</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>SDP(Session Description Protocol)，即会话描述协议，为会话通知、会话邀请和其它形式的多媒体会话初始化等目的提供了<code>多媒体会话描述</code>，在rfc2327中定义。</p>
<ul>
<li>SDP至少需要包含:<ul>
<li>会话名称及意图</li>
<li>会话有效时间</li>
<li>媒体流信息（类型、地址、端口、格式等）</li>
</ul>
</li>
</ul>
<h2 id="协议格式"><a href="#协议格式" class="headerlink" title="协议格式"></a><a href="http://www.ietf.org/rfc/rfc2327.txt" target="_blank" rel="noopener">协议格式</a></h2><ul>
<li>协议以key=value形式<pre>
v=0
o=102 2048 497 IN IP4 192.168.0.104
s=Talk
c=IN IP4 192.168.0.104
b=AS:380
t=0 0
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
m=audio 7076 RTP/AVP 120 111 110 0 8 101
a=rtpmap:120 SILK/16000
a=rtpmap:111 speex/16000
a=fmtp:111 vbr=on
a=rtpmap:110 speex/8000
a=fmtp:110 vbr=on
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
</pre>

</li>
</ul>
<h2 id="keys-包含Session，Time，Media"><a href="#keys-包含Session，Time，Media" class="headerlink" title="keys 包含Session，Time，Media"></a>keys 包含Session，Time，Media</h2><h4 id="Session-description"><a href="#Session-description" class="headerlink" title="Session description"></a>Session description</h4><ul>
<li>v=  (protocol version)<ul>
<li>没有次版本</li>
</ul>
</li>
<li>o=  (owner/creator and session identifier).<ul>
<li>o=username session-id version network—type address-type address<ul>
<li>“IN” = Internet</li>
<li>“IP4” = ipv4</li>
</ul>
</li>
</ul>
</li>
<li>s=  (session name)</li>
<li>i=* (session information)</li>
<li>u=* (URI of description)</li>
<li>e=* (email address)</li>
<li>p=* (phone number)</li>
<li>c=* (connection information - not required if included in all media)<ul>
<li>c=network-type address-type connection-address</li>
</ul>
</li>
<li>b=* (bandwidth information)<ul>
<li>b=modifier:bandwidth-value(kpb/s)</li>
</ul>
</li>
<li>One or more time descriptions (see below)</li>
<li>z=* (time zone adjustments)</li>
<li>k=* (encryption key)</li>
<li>a=* (zero or more session attribute lines)<ul>
<li>a=attribute:value …</li>
</ul>
</li>
<li>Zero or more media descriptions (see below)<h4 id="Time-description"><a href="#Time-description" class="headerlink" title="Time description"></a>Time description</h4></li>
<li>t=  (time the session is active)<ul>
<li>t=start-time stop-time, 若为0 0，则视为永久会话</li>
</ul>
</li>
<li>r=* (zero or more repeat times)<ul>
<li>r=repeat-interval active-duration list-of-offsets-from-start-time<h4 id="Media-description"><a href="#Media-description" class="headerlink" title="Media description"></a>Media description</h4></li>
</ul>
</li>
<li>m=  (media name and transport address)<ul>
<li>m=media port transport fmt-list</li>
<li>a=rtpmap:payload-type encoding-name/clock-rate[/encoding-parameters]</li>
</ul>
</li>
<li>i=* (media title)</li>
<li>c=* (connection information - optional if included at session-level)</li>
<li>b=* (bandwidth information)</li>
<li>k=* (encryption key)</li>
<li>a=* (zero or more media attribute lines)</li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/11/07/2014-11-07-asterisk在macosx下编译/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/11/07/2014-11-07-asterisk在macosx下编译/" itemprop="url">Asterisk 技术点</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-11-07T00:00:00+08:00">
                2014-11-07
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/音视频/" itemprop="url" rel="index">
                    <span itemprop="name">音视频</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>Asterisk 是一个开放源代码的软件VoIP PBX系统，它是一个运行在Linux环境下的纯软件实施方案。这里我将记录在编译和使用Asterisk遇到的问题和解决思路.</p>
<ul>
<li>brew install apple-gcc-4.2</li>
<li>./configure CC=gcc-4.2</li>
<li>define RONLY 0x1</li>
</ul>
<p>Q:process_sdp: ignoring ‘video’ media offer because port number is zero</p>
<p>A:说明视频编码不支持，core show codecs video查看支持的视频编码（linphone默认只支持vp8）</p>
<h2 id="NAT类型"><a href="#NAT类型" class="headerlink" title="NAT类型"></a>NAT类型</h2><p><a href="http://blog.163.com/hlz_2599/blog/static/1423784742012317102533915/" target="_blank" rel="noopener">NAT分类</a></p>
<h2 id="Linphone"><a href="#Linphone" class="headerlink" title="Linphone"></a>Linphone</h2><h6 id="Stun-Server"><a href="#Stun-Server" class="headerlink" title="Stun Server"></a>Stun Server</h6><p>当设置Stun Server后, Linphone会获取从Stun Server获取到公网IP和port，并在发送SIP时填充Contact，当没有设置时，则Asterisk会返回，填写Recieved和rport</p>
<pre>
12:34:24.516868 IP xuwenfas-iPhone.63627 > 192.168.60.151.5060: SIP, length: 411
Eh...?..@..$......<.........register sip:192.168.60.151="" sip="" 2.0="" via:="" udp="" 192.168.1.131:63627;branch="z9hG4bK.PcrNcrd8a;<font" color="00ff00">rport
From: < sip:112@192.168.60.151>;tag=~wyqkEm4k
To: sip:112@192.168.60.151
CSeq: 20 REGISTER
Call-ID: QuDP68~7EC
Max-Forwards: 70
Supported: outbound
Contact: < sip:112@192.168.1.131:63627>;+sip.instance="< urn:uuid:f402ede7-9815-42d5-b0c5-66d7dabf93ba>"
Expires: 3600
User-Agent: (belle-sip/1.3.3)


12:34:24.518448 IP 192.168.60.151.5060 > xuwenfas-iPhone.63627: SIP, length: 530
E.......?..E..<............osip 200="" 2.0="" ok="" via:="" sip="" udp="" 192.168.1.131:63627;branch="z9hG4bK.PcrNcrd8a;<font" color="00ff00">received=192.168.60.147;rport=63627
From: < sip:112@192.168.60.151>;tag=~wyqkEm4k
To: sip:112@192.168.60.151;tag=as16758747
Call-ID: QuDP68~7EC
CSeq: 20 REGISTER
Server: Asterisk PBX SVN-trunk-r423130
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Expires: 3600
Contact: < sip:112@192.168.1.131:63627>;expires=3600
Date: Tue, 18 Nov 2014 00:25:29 GMT
Content-Length: 0


12:34:25.381597 IP xuwenfas-iPhone.63627 > 192.168.60.151.5060: SIP, length: 433
Eh......@..x......<.........register sip:192.168.60.151="" sip="" 2.0="" via:="" udp="" 192.168.1.131:63627;branch="z9hG4bK.~kn9Nn2n7;rport" from:="" <sip:112@192.168.60.151="">;tag=hQmZSm18L
To: sip:112@192.168.60.151
CSeq: 20 REGISTER
Call-ID: nPk8A34HWK
Max-Forwards: 70
Supported: outbound
<font color="00ff00">Contact: < sip:112@192.168.60.147:63627></font>;+sip.instance="< urn:uuid:f402ede7-9815-42d5-b0c5-66d7dabf93ba>"
Expires: 3600
User-Agent: LinphoneIPhone/2.2.3 (belle-sip/1.3.3)

</.........register></............osip></.........register></pre>

<h2 id="rport"><a href="#rport" class="headerlink" title="rport"></a>rport</h2><p>获得IP地址是在Via头中带上received参数。为了得到端口信息，也参考了这种方式，即在Via头中带上rport属性来指明端口信息。</p>
<p>如果是支持rport机制的服务器，它需要在接收到的请求中检查Via头是否包含一个没有值的rport参数。如果有，它需要在回应中带上rport的值，这与received的处理类似。</p>
<pre>
12:09:59.566063 IP xuwenfas-iPhone.61710 > 192.168.60.151.5060: SIP, length: 433
Eh......@..I......<.......z.register sip:192.168.60.151="" sip="" 2.0="" via:="" udp="" 192.168.1.131:61710;branch="z9hG4bK.ccoKJW05t;rport" from:="" <sip:112@192.168.60.151="">;tag=CDqPrLUqI
To: sip:112@192.168.60.151
CSeq: 24 REGISTER
Call-ID: 81nl08JxWA
Max-Forwards: 70
Supported: outbound
Contact: <sip:112@192.168.60.147:61710>;+sip.instance="<urn:uuid:f402ede7-9815-42d5-b0c5-66d7dabf93ba>"
Expires: 3600
User-Agent: LinphoneIPhone/2.2.3 (belle-sip/1.3.3)


12:09:59.567578 IP 192.168.60.151.5060 > xuwenfas-iPhone.61710: SIP, length: 531
E../....?..N..<...........s 200="" sip="" 2.0="" ok="" via:="" udp="" 192.168.1.131:61710;branch="z9hG4bK.ccoKJW05t;received=192.168.60.147;rport=61710" from:="" <sip:112@192.168.60.151="">;tag=CDqPrLUqI
To: sip:112@192.168.60.151;tag=as4b4f12a7
Call-ID: 81nl08JxWA
CSeq: 24 REGISTER
Server: Asterisk PBX SVN-trunk-r423130
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Expires: 3600
Contact: <sip:112@192.168.60.147:61710>;expires=3600
Date: Tue, 18 Nov 2014 00:01:04 GMT
Content-Length: 0

</sip:112@192.168.60.147:61710></...........s></urn:uuid:f402ede7-9815-42d5-b0c5-66d7dabf93ba></sip:112@192.168.60.147:61710></.......z.register></pre>

<h2 id="SIP-conf"><a href="#SIP-conf" class="headerlink" title="SIP.conf"></a>SIP.conf</h2><ul>
<li>autocreatepeer=yes 允许自动创建节点</li>
<li>context=xx，指定拨号规则（定义在extension.conf中）</li>
<li>directmedia 见canreinvite</li>
<li>directrtpsetup</li>
<li><p>canreinvite 重定向媒体流，在1.6.2后改为directmedia</p>
<ul>
<li><p>yes - allow RTP media direct</p>
<figure class="highlight plain"><figcaption><span>means that this SIP is _always_ able to receive direct RTP media,from any other peer, regardless of IP address or network route.```</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">* no - deny re-invites(转发)</span><br><span class="line">```This means that this SIP peer is not able to receive direct RTP media,from any other peer, regardless of IP address or network route.</span><br></pre></td></tr></table></figure>
</li>
<li><p>nonat - allow reinvite when local, deny reinvite when NAT</p>
</li>
<li>update - use UPDATE instead of INVITE</li>
<li>update,nonat - use UPDATE when local, deny when NAT</li>
</ul>
</li>
<li><p>allow 允许编解码器</p>
</li>
<li>allowguest 允许来电</li>
<li>media_address 设定媒体流地址</li>
<li>externip - 外网IP，与localnet配合用，当呼入的ip与localnet不在同一个网段，则用externip替换sdp中的ip</li>
<li>localnet=192.168.2.0/255.255.255.0。。。可以有多个localnet（多网卡情况）</li>
<li><p>nat</p>
<ul>
<li>yes - forces RFC 3581 behavior and enables symmetric RTP support</li>
<li>no - only enables RFC 3581 behavior if the remote side requests it and disables symmetric RTP support</li>
<li>force_rport -  forces RFC 3581 behavior and disables symmetric RTP support</li>
<li><p>comedia - enables RFC 3581 behavior if the remote side requests it and enables symmetric RTP support.</p>
</li>
<li><p>force_rport+comedia = yes</p>
</li>
</ul>
</li>
</ul>
<h2 id="UPDATE"><a href="#UPDATE" class="headerlink" title="UPDATE"></a>UPDATE</h2><p>SIP的UPDATE（<a href="https://tools.ietf.org/html/rfc3311" target="_blank" rel="noopener">RFC3311</a>）消息是SIP扩展的一种机制，用以在通话尚未建立的时候更新媒体流状态的一种机制。</p>
<p>INVITE — UPDATE — REINVITE</p>
<h2 id="会话流程"><a href="#会话流程" class="headerlink" title="会话流程"></a>会话流程</h2><p><code>When SIP initiates the call, the INVITE message contains the information on where to send the media streams. Asterisk uses itself as the end-points of media streams when setting up the call. Once the call has been accepted, Asterisk sends another (re)INVITE message to the clients with the information necessary to have the two clients send the media streams directly to each other.</code></p>
<p>理解: 当SIP发起会话时，INVITE通过SDP携带媒体流传输需要的信息（IP、PORT），Asterisk会将自己作为媒体流接受者，一旦邀请被接受，Asterisk会发送带有媒体流信息的(re)INVITE给客户端，以便客户端之间建立P2P连接.<br>当以下条件不会发送(re)INVITE:</p>
<ul>
<li>canreinvite=NO</li>
<li>客户端使用不同的编解码器</li>
<li>Dial包含 ‘’t’’, ‘’T”, “h”, “H”, “w”, “W” or “L” (with multiple arguments) </li>
</ul>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/10/23/2014-10-23-ftp自动化登录及一键上传/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/10/23/2014-10-23-ftp自动化登录及一键上传/" itemprop="url">ftp自动化登录及一键上传</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-10-23T00:00:00+08:00">
                2014-10-23
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/SHELL/" itemprop="url" rel="index">
                    <span itemprop="name">SHELL</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>吐槽: 最近注册了一个空间，需要通过ftp来管理空间文件，命令行用惯了，不想用FileZilla类似的界面软件，于是就想用ftp命令直接操作，网上啪啪搜了一堆ftp命令使用教程，用起来还算简单，可发现老断，经常需要重新登录，够烦的，有时紧紧只想上传一个文件，却把大部分时间花在登录输密码上，想想应该有自动化的方法，于是开启了折腾ftp自动化的旅途.</p>
<p>##自动化登录<br>首先，肯定是登录，能够把登录自动化，那得提高多少效率啊！！！！</p>
<p>网上找了下发现ftp默认会加载~/.netrc配置文件，当然也可以通过-N来指定netrc路径，下面简单介绍netrc的设置内容:</p>
<ul>
<li>default login \<loginname> password \<password> ;设置默认登录用户及密码</password></loginname></li>
<li>runique ;防止同名覆盖</li>
<li>macdef ;宏定义，以空行结束，若名称为init则会自动执行</li>
</ul>
<p>下面是我的netrc文件:</p>
<pre>
default login xxxxxxxx password xxxxxxxxx
macdef init
cd htdocs/res

</pre>
利用上述脚本，我就可以轻松登录ftp，并进入htdocs文件夹.

##一键上传
对于ftp的上传，主要是利用了put命令，当过程太麻烦了，首先需要登录，cd到某个文件夹，之后put，一大串的操作，是否有办法批处理化呢，答案是肯定了.

结合管道+自动化登录就可以实现了，例如我要上次当前目前下到hello.txt到ftp服务器上，我只有执行如下命令:
<pre>
xuwenfadeMacBook-Pro-2:~ wenva$ echo 'put hello.txt'|ftp ftp.freekj.cn
Connected to ftp.freekj.cn.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 302 of 1900 allowed.
220-Local time is now 15:32. Server port: 21.
220-This is a private system - No anonymous login
220 You will be disconnected after 60 seconds of inactivity.
331 User bynkj_1 OK. Password required
230 OK. Current restricted directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
cd htdocs/res
250 OK. Current directory is /htdocs/res
local: hello.txt remote: hello.txt
229 Extended Passive mode OK (|||8378|)
150 Accepted data connection
     0        0.00 KiB/s 
226 File successfully transferred
221-Goodbye. You uploaded 0 and downloaded 0 kbytes.
221 Logout.
</pre>

<p>上述虽然可以一次性执行，但输入那么一大串字符，够累的，于是得继续优化，通过脚本fput来实现参数的传递</p>
<pre>
echo "put $1"|ftp ftp.freekj.cn
</pre>

<p>之后通过.bash_profile来alias一个fput命令，如下</p>
<pre>
alias fput='~/xtool/fput.sh' 
</pre>

<p>有了上面的命令，我只要执行<code>fput filename</code>就可以实现文件的一键上传.</p>
<p>综述，有了上述的基础，就可以实现一键删除、一键创建目录等，还可以批处理.</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/10/23/2014-10-23-sed命令使用/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/10/23/2014-10-23-sed命令使用/" itemprop="url">sed命令学习</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-10-23T00:00:00+08:00">
                2014-10-23
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/SHELL/" itemprop="url" rel="index">
                    <span itemprop="name">SHELL</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>sed 是一种在线编辑器，它一次处理一行内容.可以在不用打开文件进行类似vim的操作，如插入、删除、替换等.</p>
<h3 id="Usage"><a href="#Usage" class="headerlink" title="Usage"></a>Usage</h3><pre><code>sed [options] &apos;pattern + action&apos; file(s) 
pattern: 行号、匹配等
action: 动作
</code></pre><h4 id="options"><a href="#options" class="headerlink" title="options"></a>options</h4><ul>
<li>-h 帮助</li>
<li>-v 版本</li>
<li>….</li>
</ul>
<p>可以man来查看帮助</p>
<h4 id="command"><a href="#command" class="headerlink" title="command"></a>command</h4><p>名称|命令|语法|说明<br>|:–<br>替换|s|[address]s/pattern/replacement/flags    |替换匹配的内容,flags有1-255表示替换几次，g全局替换，p打印匹配，w file写入匹配<br>删除|d|[address]d|删除匹配的行<br>插入|i|[line-address]i\text|在匹配行的前方插入文本，输入方法：sed ‘1i\换行text换行’<br>追加|a|[line-address]a\text|在匹配行的后方插入文本，输入方法：sed ‘1a\换行text换行’<br>行替换|c|[address]c\text|将匹配的行替换成文本text<br>打印行|p|[address]p|打印在模式空间中的行<br>打印行号|=|[address]=|打印当前行行号<br>打印行|l|[address]l|打印在模式空间中的行，同时显示控制字符<br>转换字符|y|[address]y/SET1/SET2/|将SET1中出现的字符替换成SET2中对应位置的字符,SET1表示字符集，如sed ‘y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/‘表示小写替换成大写<br>读取下一行|n|[address]n|将下一行的内容读取到模式空间<br>读文件|r|[line-address]r file|将指定的文件读取到匹配行之后<br>写文件|w|[address]w file    |将匹配地址的所有行输出到指定的文件中<br>退出|q|[line-address]q|读取到匹配的行之后即退出</p>
<p>源内容:</p>
<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls
1.txt
2.txt
3.txt
</pre>

<ul>
<li>s/re/string/ 替换,如果是s/re/string/g则全局替换<br><pre><br>xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed ‘s/1/5/‘<br>5.txt<br>2.txt<br>3.txt<br></pre><br>PS: <code>s///</code>是一个替换命令，可以跟其他命令组合，比如<br><pre><br>bogon:9 starnet$ ls|sed ‘1s/txt/doc/‘<br>1.doc<br>2.txt<br>3.txt<br></pre><br>PS: 表示只替换第一行</li>
</ul>
<pre>
bogon:9 starnet$ ls|sed -n  -e '/1/,/2/s/txt/doc/gp'
1.doc
2.doc
</pre>
PS: 从匹配1的行开始，以含有2的行结束（至少第二行，找不到则默认到最后一行），替换txt为doc，并通过p打印，-n表示不输出每行内容.

* = 显示行号
<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed '='
1
1.txt
2
2.txt
3
3.txt
</pre>
* d 删除行， 2d删除第二行，$d删除最后一行，2,$d删除第二行到尾行
<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed 'd'
</pre>

<h4 id="元字符"><a href="#元字符" class="headerlink" title="元字符"></a>元字符</h4><ul>
<li>^ 行首，如行首插入0<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed 's/^/0/g'
01.txt
02.txt
03.txt
</pre></li>
<li>$ 行尾，如行尾插入0<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed 's/$/0/g'
1.txt0
2.txt0
3.txt0
</pre></li>
<li>. 一个任意字符，如将所有字符替换为0<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed 's/./0/g'
00000
00000
00000
</pre></li>
<li>* 零或多个字符 </li>
<li>[] 范围内<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed 's/[1].txt/asdf/g'
asdf
2.txt
3.txt
</pre></li>
<li>[^] 范围外<pre>
xuwenfadeMacBook-Pro-2:sed_test wenva$ ls|sed 's/[^1-2].txt/asdf/g'
1.txt
2.txt
asdf
</pre>

</li>
</ul>
<h3 id="多行模式"><a href="#多行模式" class="headerlink" title="多行模式"></a>多行模式</h3><ul>
<li>n - 读取下一行，并替换上一行</li>
<li>N - 读取下一行，并追加到上一行尾部</li>
<li>p - 打印模式空间内全部内容</li>
<li>P - 打印第一行(\n)</li>
<li>d - 删除模式空间全部内容，并重头开始sed</li>
<li>D - 删除第一行(\n)，对剩余模式空间重新sed</li>
</ul>
<h5 id="合并2行"><a href="#合并2行" class="headerlink" title="合并2行"></a>合并2行</h5><pre>
sed '$!N;s/\n/ /'
</pre>
PS: $表示最后一行，！表示非，$!N表示最后一行不N，其他都是N

### Pattern Space 和 Hold Space
* Pattern Space - 模式空间（流水线）
* Hold Space - 保存空间（类似于仓库）
* g - Hold -> Pattern
* G - Hold 追加-> Pattern
* h - Pattern -> Hold
* H - Pattern 追加-> Hold
* x - Hold 交换 Pattern
<pre>
反序输出
sed ‘1!G;h;$!d’mm
</pre>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallmuou.gitee.io/blog/blog/2014/09/20/2014-9-20-git服务器部署/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="smallmuou">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="smallmuou's blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/blog/2014/09/20/2014-9-20-git服务器部署/" itemprop="url">GIT服务器部署</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2014-09-20T00:00:00+08:00">
                2014-09-20
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/版本管理/" itemprop="url" rel="index">
                    <span itemprop="name">版本管理</span>
                  </a>
                </span>

                
                
              
            </span>
          

          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>考虑到目前SVN版本管理工具在模块化开发、代码审查及离线开发方面存在的不足，希望通过引入GIT版本管理工具，来解决这些不足，以促进项目的快速迭代、持续集成及代码质量改善。</p>
<p>与SVN相比，GIT存在如下比较显著的优势：</p>
<ul>
<li><p>分布式</p>
<p>  相比于SVN，GIT更倾向于分布式模式，也就是每个开发人员从服务器上clone代码后会在自己的机器上克隆一个自己的版本库，这样开发人员可以在本地创建分支，来解决临时的实务，而不耽误已有的工作，同时还可以在离线状态下查看历史版本信息。</p>
</li>
<li><p>强化Branch</p>
<p>  我们知道SVN是通过复制整个工程代码来实现分支的创建，这样不仅耗时，而且不易合并，而GIT则是通过快照机制，可以非常快速地进行分支的创建、切换等。Branch非常有利用模块化开发，可以通过从主干分支新建一个Branch来进行新特性开发，并通过Merge来合并到主分支。</p>
</li>
<li><p>审查</p>
<p>  不像SVN，任何人都可以随地随意地往主分支提交代码，SVN变得更像是一种代码备份工具，GIT增加了Merge Request来强调了代码审查的过程，通过审核机制可以保证代码的干净新鲜。</p>
<p>  若想全面了解GIT与SVN相比的优劣，可以参考此<a href="http://www.worldhello.net/2012/04/12/why-git-is-better-than-svn.html" target="_blank" rel="noopener">页面</a>.</p>
</li>
</ul>
<p>###选择<br>既然需要引入GIT作为版本管理工具，那就必须架设GIT服务器，关于GIT服务器，有Github、Gitlab、Gitcafe、BitBucket等，考虑到公司代码的安全性及访问速度，需要在内网构建一个GIT私有服务器，通过了解，<a href="https://about.gitlab.com" target="_blank" rel="noopener">Gitlab</a>是构建GIT私有服务器的一个不错选择，首先是开源，公司可以自由使用，其次社区活跃，更新快，可以保证稳定性；下面我将对Gitlab的部署方法进行说明。</p>
<p>##Gitlab服务器部署</p>
<p>###Install<br>Gitlab的部署大体有两种方式:<a href="https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md" target="_blank" rel="noopener">官方installation文档</a>和<a href="https://bitnami.com/stack/gitlab" target="_blank" rel="noopener">Bitnami集成</a>，关于这两种方法，本人都尝试过，推荐Bitnami集成，原因是问题少、安装方便、可以界面化配置，下面我介绍下Bitnami安装过程的几个要点:</p>
<ul>
<li>根据你linux系统位数<a href="https://bitnami.com/stack/gitlab/installer" target="_blank" rel="noopener">到此</a>下载相应的安装包.</li>
<li>安装过程有GUI和命令行2种配置方式，可以根据个人习惯自由选择.</li>
<li>填写Gitlab管理者帐号相关信息，并请务必记住，以保证后面Web登录.</li>
<li>建议开启邮箱配置，这样方便邮件通知，具体邮箱名称和SMTP主机可根据你自己邮箱服务来设置.</li>
<li>安装过程中可能会遇到端口被占用的情况，此情况有两种解决方案，其一，将占用端口的进程kill(可以通过lsof -i:xx来查看端口占用情况)，其二，更换端口.</li>
<li>运行后可能会出现HTTP 500等服务器类型错误，可以通过查看/opt/gitlab-xx.xx.xx-x/apps/gitlab/htdocs/log中的LOG日志来找出具体的原因，然后对症下药.</li>
</ul>
<pre>
root@wenva-virtual-machine:/develop# ./bitnami-gitlab-7.3.2-0-linux-x64-installer.run 
----------------------------------------------------------------------------
Welcome to the Bitnami Gitlab Stack Setup Wizard.

----------------------------------------------------------------------------
Select the components you want to install; clear the components you do not want 
to install. Click Next when you are ready to continue.

GitLab : Y (Cannot be edited)

GitLab CI [Y/n] :

Is the selection above correct? [Y/n]: 

----------------------------------------------------------------------------
Installation folder

Please, choose a folder to install Bitnami Gitlab Stack

Select a folder [/opt/gitlab-7.3.2-0]: 

----------------------------------------------------------------------------
Create Admin account

Bitnami Gitlab Stack admin user creation

Email Address [user@example.com]: xuwenfa@star-net.cn

Login [user]: master

Password :
Please confirm your password :
----------------------------------------------------------------------------
Hostname that will be used to create internal URLs. If this value is incorrect, 
you may be unable to access your Gitlab installation from other computers. It is 
advisable to use a Domain instead of an IP address for compatibility with 
different browsers.

Domain [127.0.1.1]: 

Do you want to configure mail support? [y/N]: y

----------------------------------------------------------------------------
Configure SMTP Settings

This is required so your application can send notifications via email.

Default email provider:

[1] GMail
[2] Custom
Please choose an option [1] : 2

----------------------------------------------------------------------------
Configure SMTP Settings

This data is stored in the application configuration files and may be visible to 
others. For this reason, it is recommended that you do not use your personal 
account credentials.

Username []: xuwenfa@star-net.cn

Password :
Re-enter :
SMTP Host []: mail.star-net.cn

SMTP Port []: 25

Secure connection

[1] None
[2] SSL
[3] TLS
Please choose an option [3] : 1

----------------------------------------------------------------------------
Setup is now ready to begin installing Bitnami Gitlab Stack on your computer.

Do you want to continue? [Y/n]: 

----------------------------------------------------------------------------
Please wait while Setup installs Bitnami Gitlab Stack on your computer.

 Installing
 0% ______________ 50% ______________ 100%
 #########################################



----------------------------------------------------------------------------
Setup has finished installing Bitnami Gitlab Stack on your computer.

Info: To access the Bitnami Gitlab Stack, go to
http://127.0.1.1:80 from your browser.
Press [Enter] to continue:
</pre>

<p>###Config<br>安装并运行，在提交代码到远程服务器(即git push origin &lt;branch)的时候会出现如下错误:</p>
<pre>
xuwenfadeMacBook-Pro-2:example wenva$ git push origin master
/opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/net/http.rb:878:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED)
    from /opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/net/http.rb:878:in `open'
    from /opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/net/http.rb:878:in `block in connect'
    from /opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/timeout.rb:52:in `timeout'
    from /opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/net/http.rb:877:in `connect'
    from /opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
    from /opt/gitlab-7.3.2-0/ruby/lib/ruby/2.0.0/net/http.rb:851:in `start'
    from /opt/gitlab-7.3.2-0/apps/gitlab/gitlab-shell/lib/gitlab_net.rb:97:in `post'
    from /opt/gitlab-7.3.2-0/apps/gitlab/gitlab-shell/lib/gitlab_net.rb:27:in `allowed?'
    from /opt/gitlab-7.3.2-0/apps/gitlab/gitlab-shell/lib/gitlab_shell.rb:64:in `validate_access'
    from /opt/gitlab-7.3.2-0/apps/gitlab/gitlab-shell/lib/gitlab_shell.rb:25:in `exec'
    from /opt/gitlab-7.3.2-0/apps/gitlab/gitlab-shell/bin/gitlab-shell:16:in `<main>'
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
</main></pre>

<ul>
<li><strong>解决方案</strong></li>
</ul>
<p>编辑/home/git/gitlab-shell/config.yml，即gitlab_url改为你的IP+端口（默认是<a href="http://localhost:8080）" target="_blank" rel="noopener">http://localhost:8080）</a></p>
<pre>
...
gitlab_url: "http://192.168.60.151:80/"
...
</pre>

<p><img src="http://127.0.0.1:8080/2014-10-23_20-54-18.png =800x500" alt="image"></p>
<p>##Gitlab使用</p>
<p>###更换IP</p>
<ul>
<li>设置/home/git/gitlab-shell/config.yml的gitlab_url<pre>
...
gitlab_url: "http://192.168.60.151:80/"
...
</pre></li>
<li>设置/opt/gitlab-7.3.2-0/apps/gitlab/htdocs/gitlab_url.yml<pre>
...
gitlab:
  ## Web server settings (note: host is the FQDN, do not include http://)
  host: 192.168.60.151
  port: 80 # Set to 443 if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
  https: false # Set to true if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
...
</pre>

</li>
</ul>
<p>###服务启动和停止<br>Gitlab服务可以通过/opt/gitlab-xx.xx.xx-x/ctlscript.sh来控制，可以通过help来查看帮助说明</p>
<pre>
root@wenva-desktop:/opt/gitlab-7.3.2-0# ./ctlscript.sh help
usage: ./ctlscript.sh help
       ./ctlscript.sh (start|stop|restart|status)
       ./ctlscript.sh (start|stop|restart|status) mysql
       ./ctlscript.sh (start|stop|restart|status) apache
       ./ctlscript.sh (start|stop|restart|status) redis
       ./ctlscript.sh (start|stop|restart|status) gitlab_sidekiq
       ./ctlscript.sh (start|stop|restart|status) gitlabci_sidekiq
       ./ctlscript.sh (start|stop|restart|status) gitlabci_runner

help       - this screen
start      - start the service(s)
stop       - stop  the service(s)
restart    - restart or start the service(s)
status     - show the status of the service(s)
</pre>

<p>###备份和恢复<br>考虑到服务器迁移、代码安全等需求，需要对代码进行实时的备份，Gitlab提供的备份命令backup，下面将具体阐述如何进行备份:</p>
<ul>
<li>设置 </li>
</ul>
<p>可以通过编辑vim /opt/gitlab-7.3.2-0/apps/gitlab/htdocs/config/gitlab.yml文件来设定备份路径，找出”Backup settings”</p>
<pre>
## Backup settings
  backup:
    path: "tmp/backups"   # Relative paths are relative to Rails.root (default: tmp/backups/)
    # keep_time: 604800   # default: 0 (forever) (in seconds)

</pre>

<ul>
<li><p>备份(Backup)</p>
<p>  通过Gitlab自带的备份命令”bundle exec bin/rake gitlab:backup:create RAILS_ENV=production”,可以很容易地实现备份.</p>
</li>
</ul>
<pre>
root@wenva-desktop:/opt/gitlab-7.3.2-0# pwd
/opt/gitlab-7.3.2-0
root@wenva-desktop:/opt/gitlab-7.3.2-0# ./use_gitlab 
sh-4.1# cd apps/gitlab/htdocs/
sh-4.1# bundle exec bin/rake gitlab:backup:create RAILS_ENV=production
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
 Warning 
  You are running as user root, we hope you know what you are doing.
  Things may work/fail for the wrong reasons.
  For correct results you should run this as user git.

Dumping database ... 
Dumping MySQL database bitnami_gitlab ... [DONE]
done
Dumping repositories ...
 * master/ecommunity ... [SKIPPED]
 * wenva/mytest ... [SKIPPED]
 * wenva/xtool ... [SKIPPED]
 * wenva/helloworld ... [SKIPPED]
done
Dumping uploads ... 
done
Creating backup archive: 1413189434_gitlab_backup.tar ... done
Deleting tmp directories ... done
Deleting old backups ... skipping
sh-4.1# ls -al tmp/backups/
total 192
drwxr-xr-x 2 root root  4096 Oct 13 16:37 .
drwxrwxr-x 6 git  git   4096 Oct 11 16:57 ..
-rw-r--r-- 1 root root 40960 Oct 11 16:58 1413008522_gitlab_backup.tar
-rw-r--r-- 1 root root 40960 Oct 11 16:57 1413017852_gitlab_backup.tar
-rw-r--r-- 1 root root 51200 Oct 13 16:36 1413189369_gitlab_backup.tar
-rw-r--r-- 1 root root 51200 Oct 13 16:37 1413189434_gitlab_backup.tar
</pre>

<ul>
<li><p>恢复(Restore)</p>
<p>  通过Gitlab自带的备份命令”bundle exec bin/rake gitlab:backup:restore RAILS_ENV=production BACKUP=xxxxxx”,可以很容易地回复到时间戳xxxxxx对应的状态.</p>
</li>
</ul>
<p>###用户管理<br>当Gitlab启动后，通过浏览器输入服务器IP，就可以看到如下登录界面，可以利用配置的管理者进行登录，管理者登入Gitlab系统后，点击右上角的”Admin area”可以进入Projects、Users、Groups管理界面.可以对User和Group进行增删改操作.</p>
<p><img src="http://127.0.0.1:8080/markdown/2014-10-13_15-34-40.png" alt="image"></p>
<p>##开发模型构建</p>
<p>##GIT命令及客户端</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
  </section>

  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/blog/page/19/"><i class="fa fa-angle-left"></i></a><a class="page-number" href="/blog/">1</a><span class="space">&hellip;</span><a class="page-number" href="/blog/page/19/">19</a><span class="page-number current">20</span>
  </nav>



          </div>
          


          

        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">smallmuou</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/blog/archives/">
              
                  <span class="site-state-item-count">197</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/blog/categories/index.html">
                  <span class="site-state-item-count">12</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/smallmuou" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-globe"></i>GitHub</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">smallmuou</span>

  
</div>

    <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

    <span id="busuanzi_container_site_pv">总访问量<span id="busuanzi_value_site_pv"></span>次</span>
    <span class="post-meta-divider">|</span>



  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Muse</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/blog/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/blog/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/blog/js/src/motion.js?v=5.1.4"></script>



  
  

  

  


  <script type="text/javascript" src="/blog/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
